package com.iflytek.demo.slice;

import com.airbnb.lottie.LottieAnimationView;
import com.airbnb.lottie.value.LottieAnimationViewData;
import com.iflytek.demo.ResourceTable;
import com.iflytek.demo.ability.iat.AudioRecorder;
import com.iflytek.demo.ability.Tools;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.global.resource.RawFileDescriptor;
import ohos.global.resource.RawFileEntry;
import ohos.media.audio.AudioRenderer;
import ohos.media.audio.AudioRendererInfo;
import ohos.media.audio.AudioStreamInfo;
import ohos.media.common.Source;
import ohos.media.player.Player;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * 录音页面
 */
public class RecordSlice extends BaseSlice {

    /**
     * 录音机器
     */
    private AudioRecorder mAudioRecorder;
    /**
     * 测试的音频 mp3格式
     */
    private final String mp3Path = "resources/rawfile/deng_guan_que_lou.mp3";
    /**
     * 录音文件保存
     */
    private File mRecorderFile;

    //  Player
    private Player player;

    // 播放按钮
    private Text playBtn;
    private LottieAnimationView lottieView;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_record);
        initView();
    }

    private void initView() {
        Text record = (Text) findComponentById(ResourceTable.Id_record);
        playBtn = (Text) findComponentById(ResourceTable.Id_play);
        lottieView = (LottieAnimationView) findComponentById(ResourceTable.Id_lottie);
        {
            LottieAnimationViewData data = new LottieAnimationViewData();
            data.setFilename("voice.json");
            data.setRepeatCount(-1);
            data.autoPlay = true;
            lottieView.setAnimationData(data);
        }
        Text playMp3 = (Text) findComponentById(ResourceTable.Id_play_mp3);
        record.setText("开始录音");
        playBtn.setEnabled(false);
        lottieView.setVisibility(Component.INVISIBLE);

        record.setClickedListener(component -> {
            if (isRecording()) {
                record.setText("开始录音");
                playBtn.setEnabled(true);
                lottieView.setVisibility(Component.INVISIBLE);
                stopRecording();
            } else {
                record.setText("停止录音");
                playBtn.setEnabled(false);
                lottieView.setVisibility(Component.VISIBLE);
                startRecording();
            }
        });
        playBtn.setClickedListener(component -> {
            new Thread(() -> playPcm(mRecorderFile)).start();
        });
        playMp3.setClickedListener(component -> {
            playMp3();
        });
    }

    /**
     * 播放pcm
     *
     * @param file pcm文件
     */
    private void playPcm(File file) {
        if (file == null || !file.exists()) {
            showToast("文件不存在");
            return;
        }
        AudioStreamInfo streamInfo = new AudioStreamInfo.Builder()
                // 16kHz
                .sampleRate(16000)
                // 混音
                .audioStreamFlag(AudioStreamInfo.AudioStreamFlag.AUDIO_STREAM_FLAG_MAY_DUCK)
                // 16-bit PCM
                .encodingFormat(AudioStreamInfo.EncodingFormat.ENCODING_PCM_16BIT)
                // 单声道输出
                .channelMask(AudioStreamInfo.ChannelMask.CHANNEL_OUT_MONO)
                // 媒体类音频
                .streamUsage(AudioStreamInfo.StreamUsage.STREAM_USAGE_MEDIA)
                .build();

        AudioRendererInfo audioRendererInfo = new AudioRendererInfo.Builder().audioStreamInfo(streamInfo)
                // pcm格式的输出流
                .audioStreamOutputFlag(AudioRendererInfo.AudioStreamOutputFlag.AUDIO_STREAM_OUTPUT_FLAG_DIRECT_PCM)
                .bufferSizeInBytes(1280)
                // false表示分段传输buffer并播放，true表示整个音频流一次性传输到HAL层播放
                .isOffload(false)
                .build();

        AudioRenderer renderer = new AudioRenderer(audioRendererInfo, AudioRenderer.PlayMode.MODE_STREAM);
        renderer.start();
        try {
            FileInputStream inputStream = new FileInputStream(file);
            byte[] temp = new byte[1280];
            while (inputStream.available() > temp.length) {
                int read = inputStream.read(temp);
                renderer.write(temp, 0, read);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private boolean isRecording() {
        return mAudioRecorder != null && mAudioRecorder.isRecording();
    }

    /**
     * 开始录音
     */
    private void startRecording() {
        mRecorderFile = new File(getExternalCacheDir(), "recorder_file.pcm");
        mRecorderFile.delete();

        if (mAudioRecorder == null) {
            mAudioRecorder = new AudioRecorder();
            mAudioRecorder.initConfig();
        }
        new Thread(() -> mAudioRecorder.startRecord(data -> {
            Tools.appendFile(mRecorderFile, data);
        })).start();
    }

    /**
     * 停止录音
     */
    private void stopRecording() {
        if (mAudioRecorder != null) {
            mAudioRecorder.stopRecord();
            mAudioRecorder.release();
            mAudioRecorder = null;
        }
    }

    /**
     * 播放音频
     */
    private void playMp3() {
        try {
            // 获取项目中的 测试的音频
            RawFileEntry rawFileEntry = getContext().getResourceManager().getRawFileEntry(mp3Path);
            RawFileDescriptor rfd = rawFileEntry.openRawFileDescriptor();
            playMp3(rfd.getFileDescriptor());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 播放音频
     *
     * @param fd FileDescriptor
     */
    private void playMp3(FileDescriptor fd) {
        try {
            player = new Player(getContext());
            // 从输入流获取FD对象
            player.setSource(new Source(fd));
            player.prepare();
            player.play();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 播放音频
     *
     * @param file 源文件位置
     */
    private void playMp3(File file) {
        try {
            player = new Player(getContext());
            FileInputStream in = new FileInputStream(file);
            // 从输入流获取FD对象
            FileDescriptor fd = in.getFD();
            player.setSource(new Source(fd));
            player.prepare();
            player.play();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 停止播放
     */
    private void stopPlayMp3() {
        if (player != null && player.isNowPlaying()) {
            player.stop();
            player = null;
        }
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    protected void onStop() {
        stopPlayMp3();
        super.onStop();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }
}
